package com.dashan.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.TreeMap;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.dashan.servlets.Parameter.Option;
import com.google.appengine.repackaged.com.google.common.base.StringUtil;

@SuppressWarnings("serial")
public abstract class DashanServlet extends HttpServlet {
    
    // Abstract methods.
    public ArrayList<Parameter> getParameterList() {
        return new ArrayList<Parameter>();
    }
    public abstract String getUrlPattern();

    

    public DashanServlet() {
    }
    
    @Override
    public void init() throws ServletException {
        super.init();
    }
    
    @Override
    public void destroy() {
    }
    protected void beforeRequest(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException {
    }
    
    protected void afterRequest(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException {
    }

    @Override
    protected void service(HttpServletRequest arg0, HttpServletResponse arg1)
            throws ServletException, IOException {
        beforeRequest(arg0, arg1);
        super.service(arg0, arg1);
        afterRequest(arg0, arg1);
    }
    
    protected TreeMap<String, Parameter> loadParamters(HttpServletRequest req) throws ServletException {
        TreeMap<String, Parameter> params = new TreeMap<String, Parameter>();
        for (Parameter param : getParameterList()) {
            params.put(param.getName(), param);
        }
        
        for (Entry<String, Parameter> entry: params.entrySet()) {            
            Parameter param = entry.getValue();
            String value = req.getParameter(param.getName());
            
            switch (param.getOption()) {
            case Required:
                if (StringUtil.isEmptyOrWhitespace(value)) {
                        throw new ServletException(String.format("Lack of paramter %s.",
                                param.getName()));  
                } else {
                    param.setRawValue(value);
                }
                break;

            case Optional:
                if (StringUtil.isEmptyOrWhitespace(value)) {
                    // Ok to be empty.
                } else {
                    param.setRawValue(value);
                }
                break;
            
            case HasDefaultValue:
                if (StringUtil.isEmptyOrWhitespace(value)) {
                    // Ok to use the defalut value.
                } else {
                    param.setRawValue(value);
                }
                break;
            }
        }
        return params;
    }
    
    /** This will create a test page. */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        
        out.println("<html>");
        out.println("<head>");
        out.println("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");
        out.println(String.format("<title>Test Page for Servlet: %s</title>", getUrlPattern()));
        out.println("</head>");
        
        out.println("<body>");
        out.println(String.format("<FORM action=\"%s\" method=\"post\">", getUrlPattern()));

        for (Parameter param : getParameterList()) {
            out.print(String.format("<LABEL for=\"%s\">%s: </LABEL>", 
                                    param.getName(), param.getName()));
            out.print(String.format("<INPUT type=\"text\" name=\"%s\" value=\"%s\"></INPUT>", 
                                    param.getName(), param.getDefaultValue()));
            if (param.getDescription() != null) {
                out.print(param.getDescription());
            }
            if (param.getOption() == Option.Optional) {
                out.print("(opt)");
            }
            out.print("<BR>");
        }
        
        out.println("<INPUT type=\"submit\" value=\"Send\">");
        out.println("</FORM>");
        out.println("</body>");
    }
}
